home *** CD-ROM | disk | FTP | other *** search
- /* I-SET.c ****************************************************************
- A very simple module to allow modification of master
- environment under DOS.
- External entry points:
-
- int iset_load_envstrings (BYTEPTR envblock, char *envstrings[], unsigned *pused)
- Loads the enviromnment in an array of char *. Each entry
- is malloc'd by the function, so it is expected that
- iset_free_envstrings is called after use.
- This routine was originally internal (used by others in this module)
- but it is now public should anyone care. No checking on array
- dimensions!
- If pfree is not NULL, the functions fills it with the number of
- bytes currently used in the environment
-
- int iset_free_envstrings (char *envstrings[])
- Frees the copy alloc'd by iset_load_envstrings. It is expected
- that the last valid entry in the array is a zero-length string
- (iset_load_envstrings does this).
-
- char *iset_getenv (char *env_par)
- Just like getenv(), only this works on the original environment.
- After use of other functions in this module, the copy which
- is accessed by getenv() could be out of date in respect of
- the master. Used internally also.
-
- int iset_set_string (char *env_par, char *env_value)
- Actually a setenv() on the master environment. If a string
- with env_par isn't found, it is added to the environment.
- If env_value is NULL, the string is addedd just like UNIX.
- Note that this routine does attempt to get the strlen()
- of a NULL: in MSC 6.0, the result is 0 and no problem.
- Please look out in other cases.
-
- int iset_append_to_string (char *env_par, char *env_value, int before)
- Adds a new env_value to the end or the beginning
- of the actual value of an environment string, depending
- on before (0: append; 1: insert before).
- If the string didn't exist, it falls
- back to iset_set_string. Otherwise, the string is appended
- with a preceding semi-colon.
-
- int iset_cut_string (char *env_par, char *string_to_cut)
- The opposite of iset_append_string. If a string with name
- env_par is found, string_to_cut is searched between pairs
- of semicolons and, if found, the original string is collapsed
- to exclude it. If the string isn't found nothing is done.
-
- int iset_delete_string (char *env_par)
- Remove the identified string from the environment. This works
- also on no-value strings which can be produced by
- iset_set_string.
-
- int iset_show_strings (void)
- Will output on stdout the contents of the master environment
- and (little) additional statistics. Useful for seeing variables
- longer than 127 chars, which DOS's set will truncate to 127.
-
- This module has been extensively used. Still we don't expect it to
- work in every situation! Do complete testings because alteration
- of master environment can produce tricky situations to debug.
- You can use this source as you like provided you leave this notes
- in the module together with the variable id.
- Please note that, to assure reentrancy, all functions load a complete
- array of pointers (dimension is hardwired) so stack space might
- be an issue.
-
- I-SET was written by Shari (Davide Migliavacca) of Inferentia S.r.l.,
- via Venezian 10, 20123 Milano ITALY.
- Tel. +39.2.266680568.
- CompuServe 100016,2335
- **********************************************************/
-
- /* You can't remove this lines */
- #define VERSIONE "3.53"
- static const char *id= "I-Set " VERSIONE " " __DATE__ " " __TIME__ " Created by Shari CIS 100016,2335";
- /*******************************/
-
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #include <options.h>
-
-
- /* Should DOS grow beyond this limit, you may put
- a version checking function instead of this macro */
- #define dos_max_pathvar_length() 127
- int iset_check_length(char *env_par, int len);
-
-
- typedef unsigned char BYTE;
- typedef unsigned int WORD;
- typedef unsigned long DWORD;
- typedef BYTE _far * BYTEPTR;
- typedef WORD _far * WORDPTR;
- typedef DWORD _far *DWORDPTR;
- typedef void _far *FP;
-
-
-
- #define MK_FP(seg, off) ((FP)((DWORD)(((WORD)(off)) | ((DWORD)((WORD)(seg))) << 16 )))
-
- #define INT20h 0xCD20
-
- static char terminating_null = '\0';
- union REGS regs;
-
- typedef struct tagPSP {
- WORD int20; /* must be 0xCD20 */
- WORD alloc_end_seg; /* segment, end of allocation block */
- BYTE reserved_1;
- BYTE far_call; /* call far ... next field */
- DWORD DOS_dispatcher; /* address of DOS dispatcher */
- DWORD termination_handler;/* int 22h contents */
- DWORD ctrl_c_handler; /* int 23h contents */
- DWORD crit_err_handler; /* int 24h contents */
- WORD parent_PSP; /* UNDOCUMENTED */
- BYTE JFT[20]; /* Job file table: UNDOCUMENTED */
- WORD env_seg; /* segment of environment block */
- DWORD reserved_2;
- WORD max_opens; /* # of entries in JFT: UNDOCUMENTED */
- DWORD actual_JFT; /* Address of actual JFT: UNDOCUMENTED */
- BYTE reserved_3[36];
- BYTE FCB_1[16]; /* Default FCB #1 */
- BYTE FCB_2[20]; /* Default FCB #2 (overlaid by 1 if used)*/
- BYTE command_tail[128]; /* command tail and DTA */
- } PSP;
-
-
- typedef struct tagMCB {
- BYTE type;
- WORD owner; /* PSP of owner */
- WORD size;
- BYTE reserved[3];
- BYTE dos4[8];
- } MCB;
-
-
- static unsigned env_size(WORD envseg)
- {
- unsigned envsize;
- _asm {
- mov ax,envseg /* get segment of env */
- dec ax /* back up to MCB */
- mov es,ax
- mov ax,es:[0003h] /* get size in grafs */
- mov envsize, ax
- }
- return envsize << 4; /* multiply by paragraph size */
- }
-
-
- /* determines if seg is really a psp:
- 1) at seg-1 there must be a DOS MCB whose owner is seg
- 2) the first two bytes in seg must be 0xCD 0x20 (int 20h)
- From "Undocumented DOS" by Andrew Schulman, Byte Vol. 16, #3 (March 1991)
- */
- static int is_psp (WORD seg)
- {
- return ((((MCB _far *) MK_FP(seg-1, 0))->owner == seg) &&
- (*((WORD _far *) MK_FP(seg, 0)) == INT20h));
- }
-
-
- static WORD get_shell_psp_seg()
- {
- PSP _far *my_psp;
- PSP _far *parent_psp;
-
- /* get PSP address (int 21h fun 62h, DOS >= 3.0) */
-
- regs.h.ah = 0x62;
-
- intdos (®s, ®s);
-
- /* bx contains segment of PSP */
-
- my_psp = (PSP _far *)MK_FP(regs.x.bx, 0);
-
- do {
- parent_psp = (PSP _far *)MK_FP(my_psp->parent_PSP, 0);
- my_psp = parent_psp;
- } while (parent_psp->parent_PSP != FP_SEG(parent_psp));
-
-
- return FP_SEG(parent_psp);
- }
-
- static BYTEPTR get_envblock ()
- {
- WORD shell_psp_seg;
- PSP _far *shell_psp;
-
- shell_psp_seg = get_shell_psp_seg();
- shell_psp = (PSP _far *) MK_FP(shell_psp_seg, 0);
-
- return ((BYTEPTR) MK_FP(shell_psp->env_seg, 0));
- }
-
- int iset_load_envstrings (BYTEPTR envblock, char *envstrings[], unsigned *pused)
- {
- char _far *envpointer = (char _far *)envblock;
- size_t len;
- int i = 0;
-
- while (*envpointer != '\0') {
- len = _fstrlen (envpointer);
- envstrings[i] = (char *) malloc (len + 1);
- _fstrcpy ((char _far *) envstrings[i], envpointer);
- envpointer += (len + 1);
- ++i;
- }
- envstrings[i] = &terminating_null;
- if (pused != (unsigned *)NULL)
- *pused = (unsigned) (envpointer - envblock);
-
- return i;
- }
-
- int iset_free_envstrings (char *envstrings[])
- {
- int i = 0;
-
- while (envstrings[i][0] != '\0')
- free (envstrings[i++]);
-
- return 0;
- }
-
-
- static int search_string (char *string, char *array[])
- {
- int i = 0;
-
- while (array[i][0] != '\0')
- {
- if (!strnicmp(array[i], string, strlen(string)))
- return i;
- else
- i++;
- }
-
- return -1;
- }
-
-
- /* works on original environment, which may be different
- from our copy because of other iset_... function calls */
- char *iset_getenv (char *env_par)
- {
- char *env_strings[128];
- BYTEPTR envblock;
- int maxstring;
- int i;
- static char env_name[128];
- static char env_value[256];
- char *return_this = NULL;
- char *equal;
-
- envblock = get_envblock();
- maxstring = iset_load_envstrings (envblock, env_strings, NULL);
-
- env_value[0] = '\0';
- for (i = 0; i < maxstring; i++) {
- equal = strchr(env_strings[i], '=');
- if (equal != NULL) {
- strncpy (env_name, env_strings[i], equal - env_strings[i]);
- env_name[equal - env_strings[i]]='\0';
- }
- else
- strcpy (env_name, env_strings[i]);
- if (!stricmp(env_name, env_par)) {
- /* return value */
- if (equal==NULL)
- env_value[0] = '\0';
- else
- strcpy (env_value, ++equal);
- return_this = env_value;
- break;
- }
- }
-
-
- iset_free_envstrings(env_strings);
- return return_this;
- }
-
-
- int iset_delete_string (char *env_par)
- {
- char *env_strings[128];
- char *new_string;
- BYTEPTR envblock;
- int maxstring;
- int i;
- int this_one;
- int len;
-
- envblock = get_envblock();
- maxstring = iset_load_envstrings (envblock, env_strings, NULL);
-
- if ((this_one = search_string(env_par, env_strings)) == -1)
- {
- /* string not found - quietly exit */
- return 1;
- }
-
-
- /* throw away old string */
- new_string = env_strings[this_one];
- free (new_string);
- for (i = this_one; i < maxstring; i++)
- env_strings[i] = env_strings[i + 1];
- maxstring--;
-
- /* rebuild environment block */
- for (i = 0; i <= maxstring; i++) {
- len = strlen (env_strings[i]) + 1; /* copy null byte */
- _fmemcpy(envblock, (void _far *)env_strings[i], len);
- envblock += len;
- }
-
- *envblock = '\0';
-
- iset_free_envstrings(env_strings);
- return 0;
- }
-
-
- int iset_set_string (char *env_par, char *env_value)
- {
- char *env_strings[128];
- char *new_string;
- BYTEPTR envblock;
- unsigned envused;
- unsigned envfree;
- int maxstring;
- int i;
- int this_one;
- int len;
- int ret;
-
- if (iset_check_length(env_par, strlen(env_value) + strlen(env_par) + 2) !=0) {
- return 1;
- }
-
- envblock = get_envblock();
- maxstring = iset_load_envstrings (envblock, env_strings, &envused);
- envfree = env_size(FP_SEG(envblock)) - envused;
-
- if ((this_one = search_string(env_par, env_strings)) != -1)
- {
- #ifdef ISETDEBUG
- fprintf(stderr, "[D] Found existing %s\", env_strings[this_one]);
- #endif
- /* throw away old string and add at the end */
- new_string = env_strings[this_one];
- envfree += (strlen(new_string) + 1);
- free (new_string);
- for (i = this_one; i < maxstring; i++)
- env_strings[i] = env_strings[i + 1];
- maxstring--;
- }
-
- new_string = (char *)malloc (strlen(env_par) + strlen(env_value) + 2);
-
- if (env_value != NULL)
- sprintf(new_string, "%s=%s", strupr(env_par), env_value);
- else
- strcpy (new_string, strupr (env_par));
-
- if (strlen(new_string) + 1 <= envfree)
- {
- env_strings[maxstring] = new_string;
- ++maxstring;
- env_strings[maxstring] = &terminating_null;
-
- /* rebuild environment block */
-
-
- for (i = 0; i <= maxstring; i++) {
- len = strlen (env_strings[i]) + 1; /* copy null byte */
- _fmemcpy(envblock, (void _far *)env_strings[i], len);
- envblock += len;
- }
-
- *envblock = '\0';
- ret = 0;
- }
- else
- ret = 2;
- iset_free_envstrings(env_strings);
-
- return ret;
- }
-
- int iset_append_to_string (char *env_par, char *env_value, int before)
- {
- char *env_strings[128];
- register char *new_string;
- char *equal_sign;
- BYTEPTR envblock;
- unsigned envused;
- unsigned envfree;
- int maxstring;
- int i;
- int this_one;
- int len;
- int newlen;
- int ret;
-
- envblock = get_envblock();
- maxstring = iset_load_envstrings (envblock, env_strings, &envused);
- envfree = env_size(FP_SEG(envblock)) - envused;
- if ((this_one = search_string(env_par, env_strings)) != -1)
- {
- #ifdef ISETDEBUG
- fprintf(stderr, "[D] Found existing %s\", env_strings[this_one]);
- #endif
- /* append value to beginning of old string suffixing with a ; */
- len = strlen(env_strings[this_one]) + strlen (env_value) + 2; /* ; and nul */
- /* check existence of '=' in string. using iset_set_string
- it is possible to create an assert-only var a la Unix. Now
- we have to complete that. */
- equal_sign = strchr(env_strings[this_one], '=');
- if (equal_sign == (char *)NULL)
- ++len;
- if (len - 1 > envfree)
- ret = 2;
- else {
- if (iset_check_length(env_par, len) == 0) {
- new_string = (char *) malloc (len);
- if (equal_sign == (char *)NULL) {
- strcpy(new_string, env_strings[this_one]);
- strcat(new_string, "=");
- }
- else {
- strncpy (new_string, env_strings[this_one], equal_sign - env_strings[this_one] + 1);
- new_string[equal_sign - env_strings[this_one] + 1] = '\0';
- }
- if (before) {
- strcat (new_string, env_value);
- strcat (new_string, ";");
- strcat (new_string, equal_sign + 1);
- }
- else {
- if (strlen(equal_sign + 1) > 0) {
- strcat (new_string, equal_sign + 1);
- strcat (new_string, ";");
- }
- strcat (new_string, env_value);
- }
-
- free (env_strings[this_one]);
- env_strings[this_one] = new_string;
- ret = 0;
- }
- else
- ret = 1;
- }
- }
- else
- {
- /* simply set it */
- len = strlen(env_par) + strlen(env_value) + 2; /* = and nul */
- if (len > envfree)
- ret = 2;
- else {
- if (iset_check_length(env_par, strlen(env_value)) == 0) {
- new_string = (char *)malloc (strlen(env_par) + strlen(env_value) + 2);
- if (env_value != NULL)
- sprintf(new_string, "%s=%s", strupr(env_par), env_value);
- else
- strcpy (new_string, strupr (env_par));
- env_strings[maxstring] = new_string;
- ++maxstring;
- env_strings[maxstring] = &terminating_null;
- ret = 0;
- }
- else
- ret = 1;
- }
- }
-
-
-
- if (ret == 0) {
- /* rebuild environment block */
- for (i = 0; i <= maxstring; i++) {
- len = strlen (env_strings[i]) + 1; /* copy null byte */
- _fmemcpy(envblock, (void _far *)env_strings[i], len);
- envblock += len;
- }
-
- *envblock = '\0';
- }
- iset_free_envstrings(env_strings);
-
- return ret;
- }
-
-
- int iset_append_to_string_OLD (char *env_par, char *env_value)
- {
- char *env_strings[128];
- char *new_string;
- BYTEPTR envblock;
- unsigned envused;
- unsigned envfree;
- int maxstring;
- int i;
- int this_one;
- int len;
- int newlen;
- int ret;
-
- envblock = get_envblock();
- maxstring = iset_load_envstrings (envblock, env_strings, &envused);
- envfree = env_size(FP_SEG(envblock)) - envused;
- if ((this_one = search_string(env_par, env_strings)) != -1)
- {
- #ifdef ISETDEBUG
- fprintf(stderr, "[D] Found existing %s\", env_strings[this_one]);
- #endif
- /* append value to old string prefixing with a ; */
- len = strlen (env_value) + 2; /* ; and nul */
- if (len - 1 > envfree)
- ret = 2;
- else {
- len+= strlen (env_strings[this_one]);
- if (iset_check_length(env_par, len) == 0) {
- new_string = (char *) malloc (len);
- strcpy (new_string, env_strings[this_one]);
- strcat (new_string, ";");
- strcat (new_string, env_value);
- free (env_strings[this_one]);
- env_strings[this_one] = new_string;
- ret = 0;
- }
- else
- ret = 1;
- }
- }
- else
- {
- /* simply set it */
- len = strlen(env_par) + strlen(env_value) + 2; /* = and nul */
- if (len > envfree)
- ret = 2;
- else {
- if (iset_check_length(env_par, strlen(env_value)) == 0) {
- new_string = (char *)malloc (strlen(env_par) + strlen(env_value) + 2);
- if (env_value != NULL)
- sprintf(new_string, "%s=%s", strupr(env_par), env_value);
- else
- strcpy (new_string, strupr (env_par));
- env_strings[maxstring] = new_string;
- ++maxstring;
- env_strings[maxstring] = &terminating_null;
- ret = 0;
- }
- else
- ret = 1;
- }
- }
-
-
-
- if (ret == 0) {
- /* rebuild environment block */
- for (i = 0; i <= maxstring; i++) {
- len = strlen (env_strings[i]) + 1; /* copy null byte */
- _fmemcpy(envblock, (void _far *)env_strings[i], len);
- envblock += len;
- }
-
- *envblock = '\0';
- }
- iset_free_envstrings(env_strings);
-
- return ret;
- }
-
- int iset_check_length(char *env_par, int len)
- {
- /* special case: due to DOS limitations, and the PATH var
- * can't exceed dos_max_pathvar_length(). So we have to test */
- if (!stricmp(env_par, "PATH")) {
- if (len > dos_max_pathvar_length()) {
- fprintf(stderr, "%s: An environment variable cannot exceed 127 characters!\n", env_par);
- return(1);
- }
- }
- return (0);
- }
-
- /* If the variable is not here, ignore.
- * Else if there is no match with string_to_cut, ignore.
- * Else take care of ";" contexts!
- */
- int iset_cut_string (char *env_par, char *string_to_cut)
- {
- char *env_strings[128];
- char *temp;
- char *new_string;
- char *env_value;
- char *cutting_point;
- char *next_piece;
- char *start_string;
- char *end_string;
- BYTEPTR envblock;
- int this_one;
- int i;
- int len;
- int maxstring;
-
- envblock = get_envblock();
- maxstring = iset_load_envstrings (envblock, env_strings, NULL);
- if ((this_one = search_string(env_par, env_strings)) != -1)
- {
- /* set value starting point */
- if ((env_value = strchr(env_strings[this_one], '=')) != (char *)NULL) {
- /* check match for string_to_cut */
- /* take care: CASE SENSITIVE MATCH on value */
- /* We must take care of ; context. */
- if (strstr(++env_value, string_to_cut) != NULL) {
- temp = (char *)malloc(strlen(env_value + 1));
- start_string = env_value;
- do {
- if ((end_string = strchr(start_string, ';')) != (char *)NULL) {
- strncpy (temp, start_string, end_string - start_string);
- temp[end_string - start_string] = '\0';
- }
- else {
- strcpy (temp, start_string);
- }
- if (!strcmp(temp, string_to_cut)) {
- /* process cutting */
- strncpy (temp, env_value, start_string - env_value);
- temp[start_string - env_value]='\0';
- if (end_string != NULL)
- strcat (temp,++end_string);
- strcpy (env_value, temp);
- end_string = env_value + strlen(env_value) - 1;
- if (*end_string == ';')
- *end_string = '\0';
- break; /* exit do...while */
- }
- } while (((start_string = end_string) != NULL) && ++start_string);
- free (temp);
-
- }
- }
- }
-
-
- for (i = 0; i <= maxstring; i++) {
- /* don't copy string if orphaned (<var>= with no value) */
- temp = env_strings[i];
- if (temp[strlen(temp) - 1] != '=') {
- len = strlen (env_strings[i]) + 1; /* copy null byte */
- _fmemcpy(envblock, (void _far *)env_strings[i], len);
- envblock += len;
- }
- }
-
- *envblock = '\0';
- iset_free_envstrings(env_strings);
-
- return 0;
-
-
- }
-
-
-
-
- int iset_show_strings ()
- {
- char *env_strings[128];
- BYTEPTR envblock;
- unsigned envsize;
- unsigned envused;
- int maxstring;
- int i;
-
- envblock = get_envblock();
- maxstring = iset_load_envstrings (envblock, env_strings, &envused);
- for (i = 0; i < maxstring; i++)
- puts(env_strings[i]);
- printf("********************************\n");
- printf("Master environment at: %Fp\n", envblock);
- printf(" Size: %u\n", envsize = env_size(FP_SEG(envblock)));
- printf(" No. of strings: %d\n", maxstring);
- printf(" Bytes used: %u\n", envused);
- printf(" Free space: %u\n", envsize - envused);
- printf("********************************\n");
-
-
-
- iset_free_envstrings(env_strings);
- return 0;
- }
-
- #ifdef STANDALONE
- main(int argc, char *argv[])
- {
- POPTIONS popt;
- char *s;
-
-
- OPT_CREATE( popt, argc, argv );
-
- if (argc < 2 || Opt_IsSwitch (popt, 'h') || Opt_IsSwitch(popt, '?')) {
- Syntax();
- exit(-1);
- }
-
- if (Opt_IsSwitch(popt, 'u')) {
- if ((s = Opt_GetParameter (popt, 'u')) == NULL) {
- Syntax();
- exit(-1);
- }
- // delete string from environment
-
- iset_delete_string (s);
- }
- else if (Opt_IsSwitch (popt, 's')) {
- show_strings ();
- }
- else if (argc > 2)
- iset_set_string (argv[1], argv[2]);
- else
- iset_set_string (argv[1], NULL);
-
- return 0;
- }
-
-
- int Syntax ()
- {
- puts ("I-Set " VERSIONE);
- puts ("\tSintassi: i-set <nomevar> [<valore>]");
- puts ("\t i-set [-u <nomevar>]");
- puts ("\t i-set -s");
- puts ("\t i-set -h │ -?");
- puts ("\t-u (unset) elimina la variabile dalla tabella ambiente.");
- puts ("\t-s (show) mostra il contenuto della tabella ambiente.");
- puts ("\n (C) 1991 Shari, Inferentia S.r.l.");
-
- return 0;
- }
- #endif
-
-
-
-
-